﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Apollo.TokenUtils
{
    internal class Token
    {
        /// <summary>
        /// 关键字对照表
        /// </summary>
        public static readonly Dictionary<string, TokenType> KeywordsDict = new()
        {
            ["func"] = TokenType.FUNCTION,
            ["null"] = TokenType.NULL,
            ["true"] = TokenType.TRUE,
            ["false"] = TokenType.FALSE,
            ["if"] = TokenType.IF,

            ["else"] = TokenType.ELSE,
            ["return"] = TokenType.RETURN,
            ["while"] = TokenType.WHILE,
            ["break"] = TokenType.BREAK,
            ["continue"] = TokenType.CONTINUE,

            ["for"] = TokenType.FOR,
            ["in"] = TokenType.IN,
            ["switch"] = TokenType.SWITCH,
            ["case"] = TokenType.CASE,
            ["default"] = TokenType.DEFAULT,

            ["class"] = TokenType.CLASS,
            ["this"] = TokenType.THIS,
            ["super"] = TokenType.SUPER,
            ["from"] = TokenType.FROM,
            ["import"] = TokenType.IMPORT,

            ["as"] = TokenType.AS,
            ["async"] = TokenType.ASYNC,
            ["defer"] = TokenType.DEFER,
        };

        public TokenType Type { get;  }
        public string Literal { get;  }
        public int Line { get;  }
        public int Column { get;  }

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public Token()
        {
            Type = TokenType.ILLEGAL;
            Literal = "illeage";
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="tokeType"></param>
        /// <param name="literal"></param>
        public Token(TokenType tokeType, string literal, int line=0, int column=0)
        {
            Type = tokeType;
            Literal = literal;
            Line = line;
            Column = column;
        }

        /// <summary>
        /// 返回类型名称
        /// </summary>
        public string Name {  
            get 
            {                
                return Type.ToString();
            } 
        }

        public Token Clone()
        {
            Token token = new(Type, Literal);
            return token;
        }

        public bool Equals(TokenType tokeType)
        {
            return Type == tokeType;
        }

        public override string ToString()
        {
            return $"{Line}:{Column}\tLiteral: {Literal}\t  Type: {Type} ";
        }
    }
}
